package com.fumin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fumin.mapper.InvestmentRecordMapper;
import com.fumin.mapper.ProjectsMapper;
import com.fumin.pojo.Capital;
import com.fumin.pojo.InvestmentRecord;
import com.fumin.pojo.Projects;
import com.fumin.service.CapitalService;
import com.fumin.service.InvestmentRecordService;
import com.fumin.service.ProjectsService;
import com.fumin.util.PropertiesUtil;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.web3j.crypto.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * Created by Lingo on 2018/3/8.
 */
@Service
public class InvestmentRecordServiceImpl implements InvestmentRecordService {

    private static Logger logger = Logger.getLogger(InvestmentRecordServiceImpl.class);

    @Resource
    InvestmentRecordMapper investmentRecordMapper;
    @Resource
    ProjectsMapper projectsMapper;

    // ETH w3j 对象
    private static Web3j web3j = Web3j.build(new HttpService(
            "https://rinkeby.infura.io/9HbpOAq5gQFlldpCBRQk"));


    @Override
    public List<InvestmentRecord> selectByUserPk(Long userPk) {
        return investmentRecordMapper.selectByUserPk(userPk);
    }

    @Override
    public InvestmentRecord selectByProjectPk(Long projectPk) {
        return investmentRecordMapper.selectByProjectPk(projectPk);
    }

    @Override
    public int deleteByPrimaryKey(Long id) {
        return investmentRecordMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(InvestmentRecord record) {
        return investmentRecordMapper.insert(record);
    }

    @Override
    public int insertSelective(InvestmentRecord record) {
        return investmentRecordMapper.insertSelective(record);
    }

    @Override
    public InvestmentRecord selectByPrimaryKey(Long id) {
        return investmentRecordMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(InvestmentRecord record) {
        return investmentRecordMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public List<InvestmentRecord> selectAll() {
        return investmentRecordMapper.selectAll();
    }

    @Override
    public int updateByPrimaryKey(InvestmentRecord record) {
        return investmentRecordMapper.updateByPrimaryKey(record);
    }


    /**
     *  将用户资产转账至项目账户中
     *
     * @param capital 用户资产信息
     * @param projects 项目
     * @return
     * @throws IOException
     * @throws CipherException
     * @throws ExecutionException
     * @throws InterruptedException
     * @throws UnirestException
     */
    @Override
    public String transaction(Capital capital, Projects projects,String amount) {

        //加载钱包文件
        Credentials credentials = null;
        try {
            credentials = WalletUtils.loadCredentials(
                    capital.getAccount_pwd(), capital.getAccount_path());
        } catch (IOException e) {
            logger.error(e.getMessage());
            return null;
        } catch (CipherException e) {
            logger.error(e.getMessage());
            return null;
        }
        // 获取交易随机数 step 1 拼接url
        String nonceUrl = "https://api.etherscan.io/api?module=proxy&action=eth_getTransactionCount&address=%s&tag=latest&apikey=H6T8WITXFCYG189UEFV2FTNAGWZQIFWHQW";
        nonceUrl = String.format(nonceUrl,credentials.getAddress());
        // 获取交易随机数 step 2 发送请求并解析结果
        String strNonce = unirestRequest(nonceUrl);
        if (strNonce==null){
            return null;
        }
        // 获取交易随机数 step 3 16进制字符串转化为BigInteger
        BigInteger nonce = Numeric.toBigInt(strNonce);
        // 生成16进制交易信息
        RawTransaction rawTransaction  = RawTransaction.createEtherTransaction(
                nonce,
                Convert.toWei("20", Convert.Unit.GWEI).toBigInteger(),
                BigDecimal.valueOf(50000).toBigInteger() ,
                projects.getProject_wallet(),
                Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger()
        );
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        String hexValue = Numeric.toHexString(signedMessage);
        return hexValue;
    }

    /**
     *  提现接口
     *  适配交易接口
     * @param amount 提现金额
     * @param destinationAddr 目标钱包地址
     * @param capital
     * @return
     */
    @Override
    public String withdraw(String amount, String destinationAddr, Capital capital) {
        Projects projects = new Projects();
        projects.setProject_wallet(destinationAddr);
        return transaction(capital,projects,amount);
    }

    @Override
    public String withdraw(String hx) {
        return commitTransaction(hx);
    }

    private String unirestRequest(String url){
        String result = null;
        HttpResponse<String> response  = null;
        try {
            response = Unirest.get(url)
                    .asString();
        } catch (UnirestException e) {
            logger.error(e.getMessage());
            return null;
        }

        String body = response.getBody();
        JSONObject  resuelt=null;

        try {
            resuelt = JSON.parseObject(body);
            result = resuelt.getString("result");
        }catch (Exception e){
            logger.error(e.getMessage());

            return null;
        }
        return result;
    }


    public String commitTransaction(String hexValue) {
        // 发送交易信息至以太坊网络 step 1 拼接url
        String transactionUrl = "https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=%s&apikey=H6T8WITXFCYG189UEFV2FTNAGWZQIFWHQW";
        transactionUrl=  String.format(transactionUrl,hexValue);
        // 发送交易信息至以太坊网络 step 2 将交易信息发送至以太坊网络中，获取交易hash码
        String txHash = unirestRequest(transactionUrl);
        return txHash;
    }

}
